using System;
using System.Data;
using System.Xml;



using OR.Lazarus.Config;
using OR.Reuse.Persistence;

namespace OR.Lazarus.Library.DataTier.Compiled
{
    public class FieldDetail : OR.Lazarus.Library.DataTier.Compiled.Lazarus.FieldDetail
    {
        public ObjectDetail ParentObject
        {
            get
            {
                return (GetParentObject());
            }
        }

        public ObjectRefDetail ParentObjectRef
        {
            get
            {
                return (GetParentObjectRef());
            }
        }

        public new FieldCollection ParentCollection
        {
            get
            {
                return (GetParentCollection());
            }
            set
            {
                base.ParentCollection = value;
            }
        }

        /// <summary>
        /// Returns the FieldCollection that the current Field is a member of within a Compiled Project..
        /// </summary>
        /// <returns>A FieldCollection.</returns>
        protected virtual FieldCollection GetParentCollection()
        {
            FieldCollection vReturn = null;

            if (base.ParentCollection is FieldCollection)
            {
                vReturn = ((FieldCollection)base.ParentCollection);
            }

            return (vReturn);
        }

        /// <summary>
        /// Returns the Object that contains the field.
        /// </summary>
        /// <returns>An ObjectDetail.</returns>
        protected virtual ObjectDetail GetParentObject()
        {
            ObjectDetail vReturn = null;
            ObjectRefDetail vObjectRef = null;

            if (this.ParentEntity is ObjectDetail)
            {
                vReturn = (ObjectDetail)ParentEntity;
            }
            else
            {
                vObjectRef = this.GetParentObjectRef();

                if (vObjectRef != null)
                {
                    vReturn = vObjectRef.ParentObject;
                }
            }

            return (vReturn);
        }

        /// <summary>
        /// Returns the ObjectRefDetail that contains the field.
        /// </summary>
        /// <returns>An ObjectRefDetail</returns>
        protected virtual ObjectRefDetail GetParentObjectRef()
        {
            ObjectRefDetail vReturn = null;

            if (this.ParentEntity is ObjectRefDetail)
            {
                vReturn = (ObjectRefDetail)ParentEntity;
            }

            return (vReturn);
        }

        /// <summary>
        /// Read-only property.  Returns whether or not the current field is a foreign key (reference) to another row, which may or may not reside in another table.
        /// </summary>
        public bool IsForeignKey
        {
            get
            {
                return (this.GetIsForeignKey());
            }
        }

        /// <summary>
        /// Read-only property.  Returns whether or not the current field is the clustered index (default order) of the container.
        /// </summary>
        public bool IsPrimaryKey
        {
            get
            {
                return (this.GetIsPrimaryKey());
            }
        }

        /// <summary>
        /// Read-only property.  Returns whether or not the current field is the primary key (identifier) of a row.
        /// </summary>
        public bool IsClustered
        {
            get
            {
                return (this.GetIsClustered());
            }
        }

        /// <summary>
        /// Read-only property.  Returns whether or not the current field is a foreign key (reference) to another row, which may or may not reside in another table.
        /// </summary>
        /// <returns></returns>
        public virtual bool GetIsForeignKey()
        {
            bool vReturn = false;

            IndexDetail vIndex = this.GetForeignKey();

            vReturn = (vIndex != null);

            return (vReturn);
        }

        /// <summary>
        /// Returns the first FK index of the field.
        /// </summary>
        /// <returns></returns>
        public virtual IndexDetail GetForeignKey()
        {
            IndexDetail vReturn = null;

            foreach (IndexDetail vIndex in this.Indexes)
            {
                if (vIndex.Type == CompilerSettings.INDEXTYPE_FOREIGN)
                {
                    vReturn = vIndex;

                    break;
                }
            }

            return (vReturn);
        }

        /// <summary>
        /// Read-only property.  Returns whether or not the current field is the primary key (identifier) of a row.
        /// </summary>
        /// <returns></returns>
        public virtual bool GetIsPrimaryKey()
        {
            bool v_bReturn = false;

            foreach (IndexDetail v_oIndex in this.Indexes)
            {
                if (v_oIndex.Type == CompilerSettings.INDEXTYPE_PRIMARY)
                {
                    v_bReturn = true;

                    break;
                }
            }

            return (v_bReturn);
        }

        /// <summary>
        /// Read-only property.  Returns whether or not the current field is the clustered index (default order) of the container.
        /// </summary>
        /// <returns></returns>
        public virtual bool GetIsClustered()
        {
            bool v_bReturn = false;

            foreach (IndexDetail v_oIndex in this.Indexes)
            {
                if (v_oIndex.Type == CompilerSettings.INDEXTYPE_CLUSTERED)
                {
                    v_bReturn = true;

                    break;
                }
            }

            return (v_bReturn);
        }

        /// <summary>
        /// Creates a Method Parameter for the current Field definition.
        /// </summary>
        /// <returns>A new ParameterDetail instance, with properties set from the current Field.</returns>
        public virtual ParameterDetail ConvertToParameter()
        {
            ParameterDetail vReturn = new ParameterDetail();

            vReturn.FieldName = this.Name;
            vReturn.Name = DataUtility.CamelCase(this.Name);
            vReturn.DBName = DataUtility.CamelCase(this.DBName);
            vReturn.Type = this.DBType;
            vReturn.Size = this.Size;
            vReturn.Scale = this.Scale;
            vReturn.AutoGenerate = this.AutoGenerate;
            vReturn.Required = this.Required;
            vReturn.Description = this.Description;
            vReturn.IsForeignKey = this.IsForeignKey;

            return (vReturn);
        }
    }
}
